package com.engine.modules.ytht.controller;


import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.engine.common.baseEntity.ResponseEntity.ResponseMsg;
import com.engine.common.exception.MapperException;
import com.engine.common.exception.ServiceException;
import com.engine.common.util.ListMapAndJson;
import com.engine.init.Globle;
import com.engine.modules.vector.controller.VectorTilesController;
import com.engine.modules.ytht.entity.FieldBlockUpdateResultEntity;
import com.engine.modules.ytht.mapper.FieldBlockBindingMapper;
import com.engine.modules.ytht.service.FieldBlockBindingService;
import com.engine.modules.ytht.entity.PlotInfoEntity;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@Api(tags = "1、地块图层操作")
@ApiSort(value = 1)
@CrossOrigin
@RequestMapping("/FieldBlockBinding")
@Slf4j
public class FieldBlockBindingController {

    @Autowired
    FieldBlockBindingService fieldBlockBindingService;

    @Autowired
    FieldBlockBindingMapper fieldBlockBindingMapper;

    @Autowired
    CacheManager cacheManager;

    @Autowired
    VectorTilesController vectorTilesController;



    @ApiOperation(value = "获取地块图层矢量切片", notes = "通过切片号xyz，获取小地块图斑图层，图层名为：FieldBlock")
    @GetMapping(value = "/SelectFieldBlockLayerVectorTiles/{tablePac}/{z}/{x}/{y}")
    @ApiOperationSupport(order = 1)
    public byte[] SelectFieldBlockLayerVectorTiles(@PathVariable("z") @ApiParam(name="z",value="16",required=true)int z,
                                        @PathVariable("x") @ApiParam(name="x",value="50839",required=true)int x,
                                        @PathVariable("y") @ApiParam(name="y",value="28021",required=true)int y,
                                        @PathVariable(value = "tablePac")
                                                       @ApiParam(name="tablePac",value="53",required=true) String tablePac,
                                        HttpServletResponse response) {
        try {
            log.debug("SelectFieldBlockLayerVectorTiles:pac:"+tablePac+"|x:" + x + "|y:" + y + "|z:" + z);
            byte[] b = fieldBlockBindingService.selectPacUnionTileByXYZ(z, x, y, tablePac);
            return b;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误").toJsonBytes();
        }
    }

    @ApiOperation(value = "获取地块图层矢量切片(概视图)", notes = "通过切片号xyz，获取小地块图斑图层概视图，图层名为：FieldBlock")
    @GetMapping(value = "/SelectOverwiseVectorTiles/{tablePac}/{z}/{x}/{y}")
    @ApiOperationSupport(order = 2)
    public byte[] SelectOverwiseVectorTiles(@PathVariable("z") @ApiParam(name="z",value="16",required=true)int z,
                                                   @PathVariable("x") @ApiParam(name="x",value="50839",required=true)int x,
                                                   @PathVariable("y") @ApiParam(name="y",value="28021",required=true)int y,
                                                   @PathVariable(value = "tablePac")
                                                   @ApiParam(name="tablePac",value="53",required=true) String tablePac,
                                                   HttpServletResponse response) {
        try {
            log.debug("SelectFieldBlockLayerVectorTiles:pac:"+tablePac+"|x:" + x + "|y:" + y + "|z:" + z);
            byte[] b = fieldBlockBindingService.selectOverwisePacUnionTileByXYZ(z,x,y,"");
            return b;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误").toJsonBytes();
        }
    }


    @ApiOperation(value = "地块编码获取地块图层geojson", notes = "通过地块编码，获取地块图层的geojson")
    @GetMapping(value = "/SelectDKTCGeosjonByIds/{fbId}")
    @ApiOperationSupport(order = 2)
    public ResponseMsg SelectDKTCGeosjonByIds(@PathVariable(value = "fbId") String fbId) {
        try {
            List<Map<String, Object>> rs = fieldBlockBindingService.selectGroupGeojsonByFBId(fbId, "b_gis_polygon_qqcg_x");
            JSONObject json = ListMapAndJson.ListMap2GeojsonObject(rs);
            if (json == null)
                return ResponseMsg.fail("未查到数据");
            else
                return ResponseMsg.success("查询成功").addData(json);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("查询失败，错误：" + se.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "tf_idcs获取地块图层geojson", notes = "通过tf_idc，获取地块图层的geojson")
    @GetMapping(value = "/SelectDKTCGeosjonByTfIdc/{tablePac}")
    @ApiOperationSupport(order = 3)
    public ResponseMsg SelectDKTCGeosjonByTfIdc(@RequestParam(value = "tf_idcs") List<String> tf_idcs,
                                              @PathVariable(value = "tablePac") String tablePac,
                                              HttpServletResponse response) {
        try {
            List<Map<String, Object>> rsList = new ArrayList<>();
            for (String tf_idc : tf_idcs) {
                rsList.addAll(fieldBlockBindingService.selectGroupGeojsonByTfIdc(tf_idc, "b_gis_polygon_qqcg_x", tablePac));
            }
            JSONObject json = ListMapAndJson.ListMap2GeojsonObject(rsList);
            if (json == null)
                return ResponseMsg.fail("未查到数据");
            else
                return ResponseMsg.success("查询成功,结果："+rsList.size()+"条").addData(json);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("查询失败，错误：" + se.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "cbjyqztidcards获取地块图层geojson", notes = "通过cbjyqztidcards，获取地块图层的geojson")
    @GetMapping(value = "/SelectDKTCGeosjonBycbjyqztidcard/{tablePac}")
    @ApiOperationSupport(order = 3)
    public ResponseMsg selectGroupGeojsonBycbjyqztidcard(@RequestParam(value = "cbjyqztidcards") List<String> cbjyqztidcards,
                                                @PathVariable(value = "tablePac") String tablePac,
                                                HttpServletResponse response) {
        try {
            List<Map<String, Object>> rsList = new ArrayList<>();
            for (String cbjyqztidcard : cbjyqztidcards) {
                rsList.addAll(fieldBlockBindingService.selectGroupGeojsonBycbjyqztidcard(cbjyqztidcard, "b_gis_polygon_qqcg_x", tablePac));
            }
            JSONObject json = ListMapAndJson.ListMap2GeojsonObject(rsList);
            if (json == null)
                return ResponseMsg.fail("未查到数据");
            else
                return ResponseMsg.success("查询成功,结果："+rsList.size()+"条").addData(json);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("查询失败，错误：" + se.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "获取地块属性json", notes = "获取地块属性json")
    @GetMapping(value = "/SelectFieldBlockLayerJsonByIds/{fbId}")
    @ApiOperationSupport(order = 4)
    public ResponseMsg SelectFieldBlockLayerJsonByIds(@PathVariable(value = "fbId") String fbId) {
        try {
            Map<String, Object> stringObjectMap = fieldBlockBindingService.selectGroupDataByFBId(fbId,
                    "b_gis_polygon_qqcg_x");
            if (stringObjectMap == null)
                return ResponseMsg.fail("未查到数据");
            else
                return ResponseMsg.success("查询成功").addData(stringObjectMap);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("查询失败，错误：" + se.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }


    @ApiOperation(value = "更新地块信息", notes = "通过地块编码,写入地块的属性（业务相关的属性）,修改操作必须带准确的地块编码")
    @PostMapping(value = "/UpdatePlotInfo")
    @ApiOperationSupport(order = 5)
    public ResponseMsg UpdatePlotInfo(@RequestBody List<PlotInfoEntity> listPlotInfoEntity) {
        try {
            int send=listPlotInfoEntity.size();
            List<String> result = fieldBlockBindingService.UpdateGroupGeneralDataByMutiEntity(listPlotInfoEntity, "b_gis_polygon_qqcg_x");
            return ResponseMsg.success("数据提交："+send+"，成功："+result.size()).addData(result);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("更新失败，错误：" + se.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "geojson插入数据", notes = "通过geojson向图层插入数据:\n" +
            "1、必须包含tablePac(县级pac编码)否则会报错\n" +
            "2、不需要包含id,field_black_no,del_flag,gmt_update,gmt_create,field_source_type,increment_dkbm,field_cross_nos，包含也没用会自动生成\n" +
            "3、会检查是否有未闭合或自相交错误\n"+
            "4、地块碰撞会写入field_cross_nos字段，并返回结果\n")
    @PostMapping(value = "/InsertFieldBlockByGeojson/{tablePac}")
    @ApiOperationSupport(order = 6)
    public ResponseMsg InsertFieldBlockByGeojson(@PathVariable(value = "tablePac") String tablePac,
                                                 @RequestBody String geoJson,
                                                 HttpServletResponse response) {
        String groupName = "b_gis_polygon_qqcg_x";
        try {
            FieldBlockUpdateResultEntity result = fieldBlockBindingService.insertByGeojson(tablePac,geoJson, groupName);
            if(result.getStatus()==0)
                return ResponseMsg.fail("未插入成功").addData(result);
            return ResponseMsg.success("插入成功").addData(result);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("插入失败，错误：" + se.getMessage());
        } catch (JSONException je) {
            return ResponseMsg.fail("输入json格式有误");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "geojson更新数据", notes = "geojson更新数据:\n" +
            "1、必须包含field_black_no，将使用field_black_no进行匹配，匹配成功则修改数据\n" +
            "2、不需要包含id,del_flag,gmt_update,gmt_create,field_source_type,increment_dkbm,field_cross_nos，包含也没用不会修改\n" +
            "3、会检查是否有未闭合或自相交错误\n"+
            "4、地块碰撞会写入field_cross_nos字段，并返回结果\n")
    @PostMapping(value = "/UpdateFieldBlockByGeojson")
    @ApiOperationSupport(order = 7)
    public ResponseMsg UpdateFieldBlockByGeojson(@RequestBody String geoJson) {
        String groupName = "b_gis_polygon_qqcg_x";
        try {
            FieldBlockUpdateResultEntity result = fieldBlockBindingService.updateByGeojson(geoJson, groupName);
            if(result.getStatus()==0)
                return ResponseMsg.fail("未更新成功").addData(result);
            return ResponseMsg.success("更新成功").addData(result);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("更新失败，错误：" + se.getMessage());
        } catch (JSONException je) {
            return ResponseMsg.fail("输入json格式有误");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "逻辑删除数据", notes = "通过地块编码删除数据，逻辑删除")
    @GetMapping(value = "/DeleteFieldBlockByIdLogic/{fbId}")
    @ApiOperationSupport(order = 8)
    public ResponseMsg DeleteFieldBlockByIdLogic(@PathVariable(value = "fbId") String fbId) {
        String groupName = "b_gis_polygon_qqcg_x";
        try {
            String uuid = fieldBlockBindingService.deleteByFbIdLogic(fbId, groupName);
            if(uuid.equals(""))
                return ResponseMsg.fail("删除失败，id未匹配");
            return ResponseMsg.success("删除成功").addData(uuid);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("删除失败，错误：" + se.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "物理删除数据", notes = "通过地块编码删除数据，物理删除数据")
    @GetMapping(value = "/DeleteFieldBlockById/{fbId}")
    @ApiOperationSupport(order = 9)
    public ResponseMsg DeleteFieldBlockById(@RequestParam(value = "fbId") String fbId) {
        String groupName = "b_gis_polygon_qqcg_x";
        try {
            String uuid = fieldBlockBindingService.deleteByFbId(fbId, groupName);
            if(uuid.equals(""))
                return ResponseMsg.fail("删除失败");
            return ResponseMsg.success("删除成功").addData(uuid);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("删除失败，错误：" + se.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "检查地块碰撞", notes = "检查地块geometry碰撞,获取已有地块id,此接口不会插入数据")
    @PostMapping(value = "/CheckIntersectsBlockId/{tablePac}")
    @ApiOperationSupport(order = 10)
    public ResponseMsg CheckIntersectsBlockId(@PathVariable(value = "tablePac") String tablePac,
                                              @RequestBody String geometry) {
        String groupName = "b_gis_polygon_qqcg_x";
        String tableName=groupName+tablePac;
        if (Globle.TablePropertiesMap.get(tableName) == null)
            return  ResponseMsg.fail("数据库中表不存在或未添加进数据目录");
        try {
            List<String> list= fieldBlockBindingMapper.getIntersectsBlockFbId(geometry,tableName);
            if(list.size()==0)
                return ResponseMsg.success("无碰撞");
            else
                return ResponseMsg.success("存在碰撞地块数："+list.size()).addData(list);
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("删除失败，错误：" + se.getMessage());
        } catch (JSONException je) {
            return ResponseMsg.fail("输入json格式有误");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }

    @ApiOperation(value = "通过地块编码获取id", notes = "通过地块编码获取id")
    @PostMapping(value = "/selectIdByFieldblackNo/{fieldblackNo}")
    @ApiOperationSupport(order = 11)
    public ResponseMsg selectIdByFieldblackNo(@PathVariable(value = "fieldblackNo") String fieldblackNo) {
        try {
            String rs= fieldBlockBindingService.selectIdByFieldBlockNo(fieldblackNo);
            if(!rs.equals(""))
                return ResponseMsg.success("获取成功").addData(rs);
            else
                return ResponseMsg.fail("未查到地块id");
        } catch (ServiceException | MapperException se) {
            return ResponseMsg.fail("获取失败，错误：" + se.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsg.error("服务器内部错误");
        }
    }


}
